package doghttp

import (
  /* 标准库 */
  "net/http"
  "fmt"
  "strconv"
  // "time"

  /* 第三方库 */
  "dog.com/processor"
  "dog.com"

)

// 启动系统核心http服务
func HttpRun() {
    workMap := dog.WorkMapFactory()

    // 把实现Ijob的服务注册给http服务
    for key , _ := range workMap {
        fmt.Println("load serviceName = ", key)
        http.HandleFunc("/" + key, core.RedisLruServ)
        //http.HandleFunc(key, value.GetHandleFunc())
    }

    cfg := dog.ConfigFactory()
    // 创建核心转发队列 JobQueue, 转发实现Ijob的
    if jobQueueCapacity , err := strconv.Atoi(cfg.Core.JobQueueCapacity) ; nil == err {
        dog.JobQueue = make ( chan dog.Ijob, jobQueueCapacity)
    } else {
        return
    }

    //创建分发器
    var dispatcher *Dispatcher
    if maxWorderNum , err := strconv.Atoi(cfg.Core.MaxWorkerNum); nil == err {
        dispatcher = NewDispatcher(maxWorderNum)
    } else {
        fmt.Println("strconv err!")
        return
    }

    dispatcher.Run()

    //通过配置文件读取配置文件信息
    //读取服务堵端口号
    err:=http.ListenAndServe(":" + cfg.Service.Port, nil)
    if err != nil {
        fmt.Println("Listen Server error!")
    }

    fmt.Println("开始启动服务， port:" + cfg.Service.Port)

}

type Dispatcher struct {
  // 一个工作池， 为了注册分发请求
  WorkerPool chan chan dog.Ijob
  MaxWorkers int
}

// Worker 用来执行 Job
type Worker struct {
    WorkerPool chan chan dog.Ijob
    JobChannel chan dog.Ijob
    quit       chan bool
}

// 生成一个worker
func NewWorker (workerPool chan chan dog.Ijob) Worker{
  return Worker{ WorkerPool: workerPool,
                JobChannel: make (chan dog.Ijob),
                quit: make (chan bool) }
}

//

func (w Worker) Start () {
    go func () {
        for {
            // 注册工作渠道给
            w.WorkerPool <- w.JobChannel
            select {
            case job := <-w.JobChannel:
                job.UnpackRequest()
                job.Do()
                job.PackResponse()
                break;
            case <-w.quit:
                return
            }
        }
    }()
}

//分发器开始工作
func (d *Dispatcher) Run() {
  for i:= 0 ; i < d.MaxWorkers; i++ {
      worker := NewWorker(d.WorkerPool)
      worker.Start()
  }

  fmt.Println("dispatch start work!")
  go d.dispatch()
}

// 分发http请求
func (d *Dispatcher) dispatch() {
  for {
    select {
      case job:= <- dog.JobQueue:
          fmt.Println("i have received http message!")
          go func(job dog.Ijob) {
              jobChannel := <-d.WorkerPool
              jobChannel <- job
          }(job)
    }
  }
}

//创建一个分发器，用来分来http请求
func NewDispatcher (maxWorkers int) *Dispatcher {
    pool := make(chan chan dog.Ijob, maxWorkers)
    return &Dispatcher{WorkerPool :pool,
                       MaxWorkers : maxWorkers}
}
